<template>
  <div>
    <a-popover v-model:open="visible" trigger="click" :placement="placement">
      <slot>
        <a-tooltip title="路径选择">
          <FolderOutlined />
        </a-tooltip>
      </slot>
      <template #content>
        <a-tabs class="system-path">
          <template #rightExtra>
            <a-flex :gap="8">
              <a-tooltip title="收藏路径">
                <a-button @click="star" :disabled="selectedKeys.length === 0">
                  <StarOutlined />
                </a-button>
              </a-tooltip>
              <a-button @click="refresh">
                <reload-outlined />
              </a-button>
              <a-button type="primary" @click="confirm()">确定</a-button>
            </a-flex>
          </template>
          <a-tab-pane key="folders" tab="文件夹">
            <div title="文件夹">
              <a-directory-tree
                @select="selectPath"
                :multiple="multiple"
                :tree-data="files"
                :height="374"
                block-node
                v-model:selected-keys="selectedKeys"
                v-model:expanded-keys="expandedKeys"
                :load-data="onLoadData"
              ></a-directory-tree>
            </div>
          </a-tab-pane>
          <!-- 收藏列表 -->
          <a-tab-pane tab="收藏">
            <div>
              <a-list size="small" :data-source="systemStore.$state.starList">
                <template #renderItem="{ item }">
                  <a-list-item class="p-0">
                    <a-list-item-meta>
                      <template #title>
                        <a-tooltip :title="item">
                          <div class="path">
                            {{ item }}
                          </div>
                        </a-tooltip>
                      </template>
                    </a-list-item-meta>

                    <template #actions>
                      <a-button type="text" @click="confirm(item)">
                        <CheckOutlined />
                      </a-button>
                      <a-button type="text" @click="delStar(item)">
                        <DeleteOutlined />
                      </a-button>
                    </template>
                  </a-list-item>
                </template>
              </a-list>
            </div>
          </a-tab-pane>
        </a-tabs>
      </template>
    </a-popover>
  </div>
</template>

<script setup lang="ts">
import { getFileList } from '@/api/modules/tool/file/cache.request';
import { getSystemPath } from '@/api/modules/tool/file/file';
import useSystemStore from '@/store/system';
import { FileOutlined, FolderOutlined, StarOutlined } from '@ant-design/icons-vue';
import { message, type TreeProps } from 'ant-design-vue';
import type { EventDataNode } from 'ant-design-vue/es/tree';
import type { Key } from 'ant-design-vue/es/vc-tree-select/interface';
import { files, isFirstLoad } from './path';
import type { TooltipPlacement } from 'ant-design-vue/es/tooltip';

const systemStore = useSystemStore();
const visible = ref(false);
const expandedKeys = ref<string[]>([]);
const emit = defineEmits(['update:modelValue', 'change']);

const props = withDefaults(
  defineProps<{
    /* 是否多选 */
    multiple?: boolean;
    /* 双向绑定路径 */
    modelValue: string | undefined;
    /* 从root路径开始查询 */
    root?: string;
    /* 仅查询文件夹 */
    onlyFolder?: boolean;
    placement?: TooltipPlacement;
  }>(),
  {
    multiple: false,
    root: '',
    onlyFolder: true,
    placement: 'bottom',
  },
);

const selectedKeys = ref<string[]>([]);

const getPath = async (path: string) => {
  const cacheData = await getFileList(path, props.onlyFolder);
  files.value = cacheData.map((e: any) => {
    if (e.type === 'folder') {
      e.icon = h(FolderOutlined);
    } else {
      e.icon = h(FileOutlined);
    }
    return e;
  });
};

const onLoadData: TreeProps['loadData'] = (treeNode: EventDataNode) => {
  return new Promise<void>(async resolve => {
    if (!treeNode.dataRef) return;
    const { data } = await getSystemPath(`${treeNode.key}`, props.onlyFolder);

    treeNode.dataRef.children = data.data;
    files.value = [...files.value];
    resolve();
  });
};

const selectPath = (selectedKeys: Key[], info: any) => {
  const path = selectedKeys[0];
  if (path) {
    onLoadData(info.node);
  }
};

const refresh = () => {
  isFirstLoad.value = true;
  files.value = [];
  getPath('');
};
onMounted(() => {
  /*
    判断是否是第一次加载
    Path组件可能被页面多处引用
    避免重复发起请求，清除 {isFirstLoad}后，可重新加载文件路径
   */
  if (isFirstLoad.value) {
    getPath(props.root);
    isFirstLoad.value = false;
  }
});
/* 确定 */
const confirm = (path?: string) => {
  if (path) {
    selectedKeys.value = [path];
  }
  let selectedPath = selectedKeys.value[0];
  emit('update:modelValue', selectedPath);
  emit('change', selectedPath);
  visible.value = false;
  star();
};

/* 收藏文件路径 */
const star = () => {
  const filePath = selectedKeys.value[0];
  if (!systemStore.$state.starList.includes(filePath)) {
    systemStore.$state.starList.push(filePath);
  }
};
/* 移除star */
const delStar = (path: string) => {
  systemStore.$state.starList = systemStore.$state.starList.filter(e => e !== path);
};
</script>

<style lang="scss" scoped>
.system-path {
  min-height: 400px;
  width: 400px;
  max-width: 600px;
  :deep(.ant-card-body) {
    max-height: 400px;
    overflow-y: auto;
  }
}
:deep(.ant-tree-treenode) {
  white-space: nowrap;
}
.path {
  white-space: nowrap;
  width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
}
</style>
